package com.billy.ohos.swipe.ext.refresh;

import com.billy.ohos.swipe.SmartSwipeRefresh;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.utils.Color;
import ohos.app.Context;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

/**
 *
 * @since v1.0.3
 * @author billy.qi
 */
public class ArrowHeader extends Component implements Component.DrawTask, SmartSwipeRefresh.SmartSwipeRefreshHeader, Component.EstimateSizeListener {

    private ArrowDrawable mDrawable;
    private IArrowInitializer mInitializer;
    private int bowColor;
    private int arrowColor;
    private int stringColor;
    private int lineColor;
    private int bowLength;
    static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "my_tag");

    public static interface IArrowInitializer {
        void onArrowInit(ArrowHeader arrowHeader, ArrowDrawable arrowDrawable);
    }

    public ArrowHeader(Context context) {
        this(context, null);
    }

    public ArrowHeader(Context context, AttrSet attrs) {
        this(context, attrs, 0);
    }

    public ArrowHeader(Context context, AttrSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        if(attrs!=null){
            bowColor = AttrUtils.getColorFromAttr(attrs, "bowColor", Color.getIntColor("#EEEEEE"));
            arrowColor = AttrUtils.getColorFromAttr(attrs, "arrowColor", Color.getIntColor("#EEEEEE"));
            stringColor = AttrUtils.getColorFromAttr(attrs, "stringColor", Color.getIntColor("#EEEEEE"));
            lineColor = AttrUtils.getColorFromAttr(attrs, "stringColor", Color.getIntColor("#EEEEEE"));
            bowLength = AttrUtils.getIntegerFromAttr(attrs, "bowLength", 0);
        }else{
            bowColor =  Color.getIntColor("#EEEEEE");
            arrowColor =Color.getIntColor("#EEEEEE");
            stringColor =Color.getIntColor("#EEEEEE");
            lineColor = Color.getIntColor("#EEEEEE");
            bowLength = 0;
        }

        setEstimateSizeListener(this);
        addDrawTask(this);
    }

    public Component getView() {
        return this;
    }

    boolean measured;

    @Override
    public boolean onEstimateSize(int widthEstimateConfig, int heightEstimateConfig) {
        if (!measured) {
            int width = Component.EstimateSpec.getSize(widthEstimateConfig);
            int height = Component.EstimateSpec.getSize(heightEstimateConfig);
            setEstimatedSize(
                    Component.EstimateSpec.getChildSizeWithMode(width, width, Component.EstimateSpec.NOT_EXCEED),
                    Component.EstimateSpec.getChildSizeWithMode(height, height, Component.EstimateSpec.NOT_EXCEED));

            measured = true;
            mDrawable = ArrowDrawable.create(this, getEstimatedWidth(), getEstimatedHeight(),
                    (int) (bowLength > 0 ? bowLength : getEstimatedWidth() * .3F));
            if (bowColor != 0) {
                mDrawable.setBowColor(bowColor);
            }
            if (arrowColor != 0) {
                mDrawable.setArrowColor(arrowColor);
            }
            if (stringColor != 0) {
                mDrawable.setStringColor(stringColor);
            }
            if (lineColor != 0) {
                mDrawable.setLineColor(lineColor);
            }
            mDrawable.reset();
            if (mInitializer != null) {
                mInitializer.onArrowInit(this, mDrawable);
            }
        }
        return true;
    }


    @Override
    public void onInit(boolean horizontal) {
    }

    @Override
    public void onStartDragging() {
    }

    @Override
    public void onReset() {
        if (mDrawable != null) {
            mDrawable.reset();
        }
    }

    @Override
    public void onProgress(boolean dragging, float progress) {
        float value;
        if (progress <= .5F) {
            value = progress / 2;
        } else if (progress <= .75F) {
            value = progress - .25F;
        } else {
            value = (progress - .5F) * 2;
        }
        mDrawable.setProgress(value);
        invalidate();
    }

    @Override
    public long onFinish(boolean success) {
        if (success) {
            mDrawable.hit();
            return getHitAnimationDuration();
        } else {
            mDrawable.miss();
            return getMissAnimationDuration();
        }
    }

    private int getHitAnimationDuration() {
        return (int) (mDrawable.getHitDuration() + (mDrawable.getSkewDuration() * 8) + 400);
    }

    private int getMissAnimationDuration() {
        return ((int) mDrawable.getMissDuration()) + 100;
    }

    @Override
    public void onDataLoading() {
        mDrawable.fire();
    }


    @Override
    public void onDraw(Component component, Canvas canvas) {
        if (mDrawable != null) {
            mDrawable.draw(canvas);
        }
        getContext().getUITaskDispatcher().asyncDispatch(this::invalidate);
    }

    public IArrowInitializer getInitializer() {
        return mInitializer;
    }

    public void setInitializer(IArrowInitializer initializer) {
        this.mInitializer = initializer;
    }

    public ArrowDrawable getDrawable() {
        return mDrawable;
    }
}
